package com.tansun.rule.utils;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import org.dom4j.Element;

import com.tansun.rule.config.AppConfiguration;
import com.tansun.rule.exception.RuleDeployException;
import com.tansun.rule.pojo.EnterPoint;
import com.tansun.rule.pojo.RulePackageMeta;
import com.tansun.rule.pojo.RuleProj;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.RuleBomMapXmlConvert;
import com.tansun.rule.utils.XMLHandler;

public class DeployUtils {
	/**
	 * 读取规则包，获取规则执行信息
	 * @param droolsJar
	 * @return
	 * @throws RuleDeployException
	 */
	public static RulePackageMeta readMavenPomProp(String droolsJar) throws RuleDeployException {  
		try{
        ZipFile zf = new ZipFile(droolsJar);  
        InputStream in = new BufferedInputStream(new FileInputStream(droolsJar));  
        ZipInputStream zin = new ZipInputStream(in);  
        ZipEntry ze;  
        RulePackageMeta rpm = null;
        while ((ze = zin.getNextEntry()) != null) {  
            if (ze.isDirectory()) {
            } else {  
                //System.err.println("file - " + ze.getName() + " : "   + ze.getSize() + " bytes");  
                if(ze.getName().toString().equals("META-INF/maven/pom.properties")){
                	System.err.println("file - " + ze.getName() + " : "   + ze.getSize() + " bytes");  
                	
//                	long size = ze.getSize();  
//                	if (size > 0) {  
                		BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));  
                		String line;  
                		rpm = new RulePackageMeta();
                		while ((line = br.readLine()) != null) {  
                			System.out.println(line); 
                			if(line.split("=")[0].equals("groupId")){
                				rpm.setGroupId(line.split("=")[1]);
                			}else if(line.split("=")[0].equals("artifactId")){
                				rpm.setArtifactId(line.split("=")[1]);
                			}else if(line.split("=")[0].equals("version")){
                				rpm.setVersion(line.split("=")[1]);
                			}
        
                		}  
                		br.close();  
//                	}  
                	
                }
               // System.out.println();  
            }  
        }  
        zin.closeEntry();  
        in.close();
        return rpm;
		}catch (Exception e) {
			e.printStackTrace();
			throw new RuleDeployException("Rule package error");
		}
    }  
	
	
	/**
	 * 添加kbase ksession信息到RulePackageMeta
	 * @param rpm
	 * @param droolsJar
	 * @throws RuleDeployException
	 */
	public static void insertSessionNamefromKmodule(RulePackageMeta rpm, String droolsJar) throws RuleDeployException{
		try{
		ZipFile zf = new ZipFile(droolsJar);  
	        InputStream in = new BufferedInputStream(new FileInputStream(droolsJar));  
	        ZipInputStream zin = new ZipInputStream(in);  
	        ZipEntry ze;  
	        //RulePackageMeta rpm = null;
	        while ((ze = zin.getNextEntry()) != null) {  
	            if (ze.isDirectory()) {
	            } else {  
	                //System.err.println("file - " + ze.getName() + " : "   + ze.getSize() + " bytes");  
	                if(ze.getName().toString().equals("META-INF/kmodule.xml")){
	                	System.err.println("file - " + ze.getName() + " : "   + ze.getSize() + " bytes");  
	                	
//	                	long size = ze.getSize();  
//	                	if (size > 0) {  
	                		BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));  
	                		StringBuffer sb = new StringBuffer(); 
	                		String line;
	                		//rpm = new RulePackageMeta();
	                		while ((line = br.readLine()) != null) {  
	                			sb.append(line);
	                		}  
	                		br.close();  
//	                	}  
	                		System.out.println(sb.toString());
	                		XMLHandler xmlHandler = new XMLHandler(sb.toString());
	                		String kbaseName = xmlHandler.getRootElement().element("kbase").attributeValue("name");;//.attributeValue("name");
	                		String sessionName = xmlHandler.getRootElement().element("kbase").element("ksession").attributeValue("name");;//.attributeValue("name");
	                		rpm.setSessionName(sessionName);
	                		rpm.setKbaseName(kbaseName);
	                	
	                }
	               // System.out.println();  
	            }  
	        }  
	        zin.closeEntry();  
	        in.close();
		}catch (Exception e) {
			e.printStackTrace();
			throw new RuleDeployException("Rule package error");
		}
	}
	/**
	 * 初始化映射集合
	 */
	public static void initRuleProjMetaMap() {
		//System.out.println("项目目录："+AppConfiguration.RuleProjDeployDir);
		//File dir = new  File(AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir);
		File dir = new  File(AppConfiguration.RuleProjDeployDir);
		for (File file : dir.listFiles()) {
			if(file.isDirectory()){
				//File bomfile = new File(AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir+"/"+file.getName()+"/"+AppConfiguration.BomFile);
				File bomfile = new File(AppConfiguration.RuleProjDeployDir+"/"+file.getName()+"/"+AppConfiguration.BomFile);
				Map<String, MClass> metaMap = RuleBomMapXmlConvert.getMapping(bomfile);
				AppConfiguration.RuleProjMetaMap.put(file.getName(), metaMap);				
			}
		}
	}
	
	/**
	 * 系统启动时，从规则项目部署文件和项目配置文件中生成 RuleProj 对象
	 * @param deployFile
	 * @return
	 */
	@SuppressWarnings({"rawtypes"})
	public static RuleProj getRuleProjByDeployFile(File deployFile){
		XMLHandler xmlHandler = new XMLHandler(deployFile,"UTF-8");
		RuleProj ruleProj = new RuleProj();
		ruleProj.setType(xmlHandler.getElement("/Deploy/type").getTextTrim());
		ruleProj.setUserName(xmlHandler.getElement("/Deploy/username").getTextTrim());
		ruleProj.setTarget(xmlHandler.getElement("/Deploy/target").getTextTrim());
		ruleProj.setProjectName(xmlHandler.getElement("/Deploy/projectName").getTextTrim());
		ruleProj.setProjectZhName(xmlHandler.getElement("/Deploy/projectZhName").getTextTrim());
		ruleProj.setVersion(xmlHandler.getElement("/Deploy/version").getTextTrim());
		//ruleProj.setDatatime(xmlHandler.getElement("/Deploy/datatime").getTextTrim());
		
		List list = xmlHandler.getListElement("/Deploy/enterPointList/enterPoint");
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Element ele = (Element) iterator.next();
			EnterPoint enterPoint = new EnterPoint();
			enterPoint.setName(xmlHandler.getElementText(ele, "name"));
			enterPoint.setCode(xmlHandler.getElementText(ele, "code"));
			enterPoint.setRuleflowId(xmlHandler.getElementText(ele, "ruleflowId"));
			enterPoint.setControl(xmlHandler.getElementText(ele, "control"));
			enterPoint.setDesc(xmlHandler.getElementText(ele, "desc"));
			ruleProj.getEnterPointList().add(enterPoint);
		}
		//
//		appendRuleProjExcuteInfo(ruleProj);
//		String file = AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir+"/"+AppConfiguration.RuleProjConf;
		String file = AppConfiguration.RuleProjDeployDir+"/"+AppConfiguration.RuleProjConf;
		String line = IOUtils.getFirstLineByPatternStr("^"+ruleProj.getProjectName()+"@@.*",file);
		if(null!=line){
			String[] items = line.split("@@");
			ruleProj.setFirstDeployTime(items[1]);
			ruleProj.setLastDeployTime(items[2]);
			ruleProj.setLastRebootTime(items[3]);
			ruleProj.setSessionMaxTotal(Integer.parseInt(items[4]));
			ruleProj.setSessionMaxIdle(Integer.parseInt(items[5]));
			ruleProj.setStatus(1);
			
		}
		return ruleProj;
	}
	/**
	 * 回写到文件 入口点的开启和关闭
	 * @param deployFile
	 * @param ruleProj
	 */
	public static void setEnterPointOnOff(String deployFile, RuleProj ruleProj){
		
		XMLHandler xmlHandler = new XMLHandler(new File(deployFile),"UTF-8");
		List list = xmlHandler.getListElement("/Deploy/enterPointList/enterPoint");
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Element el = (Element) iterator.next();
//			System.out.println(el.element("name").getText());
			
			for (EnterPoint ep : ruleProj.getEnterPointList()) {
				if(el.element("ruleflowId").getText().equals(ep.getRuleflowId())){
					el.element("control").setText(ep.getControl());
				}
					
			}
		}
		xmlHandler.writeXmlFile(deployFile, "UTF-8");
	}
//	public static void appendRuleProjExcuteInfo(RuleProj ruleProj) {
//		
//	}
	/**
	 * 插入或更新规则项目配置信息
	 * @param ruleProj
	 * @throws RuleDeployException
	 */
	public static void editRuleProjExcuteInfo(RuleProj ruleProj) throws RuleDeployException{
		//String file = AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir+"/"+AppConfiguration.RuleProjConf;
		String file = AppConfiguration.RuleProjDeployDir+"/"+AppConfiguration.RuleProjConf;
		
		String ruleProjExcuteInfo =  IOUtils.getFirstLineByPatternStr("^"+ruleProj.getProjectName()+"@@.*",file);
		String addStr = ruleProj.getProjectName()+"@@"+
						ruleProj.getFirstDeployTime()+"@@"+
						ruleProj.getLastDeployTime()+"@@"+
						ruleProj.getLastRebootTime()+"@@"+
						ruleProj.getSessionMaxTotal()+"@@"+
						ruleProj.getSessionMaxIdle();
		if(ruleProjExcuteInfo == null){
			IOUtils.appendFileALine(addStr, file);
			return;
		}
		
		boolean modify = IOUtils.modifyFirstLineByPatternStr(addStr,"^"+ruleProj.getProjectName()+"@@.*",file);
		if(modify==false){
			throw new RuleDeployException("规则执行配置更新有误!");
		}
		
	}
	/**
	 * 加载所有的规则项目配置 包括部署信息和配置信息
	 * @param path
	 * @return
	 */
	public static Map<String, RuleProj> buildRuleProjs(String path) {
		File dir = new File(path);
		if(!dir.isDirectory()){
			return null;
		}
		Map<String, File> deployFilestemp = new HashMap<String, File>();
		Map<String, RuleProj> deployFiles = new HashMap<String, RuleProj>();
		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			if(files[i].isDirectory()){
				for(File file : files[i].listFiles()){
					if(file.isFile() && file.getName().equals(AppConfiguration.DepFile)){
						deployFilestemp.put(files[i].getName(), file);
					}
					
				}
			}
		}
		Set<String> keys = deployFilestemp.keySet();
		for(String key: keys){
			RuleProj rp = getRuleProjByDeployFile(deployFilestemp.get(key));
			deployFiles.put(rp.getProjectName(), rp);
		}
		
		
		return deployFiles;
	}
	
	public static String readRuleConfigFromJar(File file, String fileName) throws Exception {  
        ZipFile zf = new ZipFile(file);  
        InputStream in = new BufferedInputStream(new FileInputStream(file));  
        ZipInputStream zin = new ZipInputStream(in);  
        ZipEntry ze;  
        StringBuffer sb = new StringBuffer();
        while ((ze = zin.getNextEntry()) != null) {  
            if (ze.isDirectory()) {
            } else {  
               // System.err.println("file - " + ze.getName() + " : "   + ze.getSize() + " bytes");  
               // long size = ze.getSize();  
                if (ze.getName().endsWith(fileName)) {  
                    BufferedReader br = new BufferedReader(  
                            new InputStreamReader(zf.getInputStream(ze), "UTF-8"));  
                    String line;  
                    while ((line = br.readLine()) != null) {  
                       // System.out.println(line);  
                        sb.append(line);
                    }  
                    br.close(); 
                    break;
                }  
                System.out.println();  
            }  
        }  
        if(zin!=null){
	        zin.closeEntry();
	        zin.close();
        }
        if(in!=null){
        	in.close();
        }
        return sb.toString();
    }
}
